﻿@using System.Globalization
@using Microsoft.FluentUI.AspNetCore.Components.Extensions
@using Xunit
@inherits TestContext

@code
{
    [Fact]
    public void FluentCalendar_ValueChanged()
    {
        const string DAY = "2022-06-01";
        DateTime? value = DateTime.UtcNow;
        Action<DateTime?> ChangedCallback = (e) => { value = e!.Value; };

        // Arrange
        var calendar = Render(@<FluentCalendar Value="@value" ValueChanged="ChangedCallback" PickerMonth="@DateTime.Parse(DAY)">Pick a date</FluentCalendar>);

        // Act
        var day = calendar.Find($"div[value='{DAY}']");
        day?.Click();

        var selectedDay = calendar.Find($"div[value='{DAY}']");

        // Assert
        Assert.Equal<DateTime?>(value, DateTime.Parse($"2022-06-{selectedDay.TextContent}"));
    }

    [Theory]
    [InlineData(CalendarViews.Days, "en-us", "15")]
    [InlineData(CalendarViews.Days, "fr-fr", "15")]
    [InlineData(CalendarViews.Months, "en-us", "Apr")]
    [InlineData(CalendarViews.Months, "fr-fr", "Avr.")]
    [InlineData(CalendarViews.Years, "en-us", "2022")]
    [InlineData(CalendarViews.Years, "fr-fr", "2022")]
    public void FluentCalendar_Culture_View_ValueChanged(CalendarViews view, string cultureName, string assertContent)
    {
        DateTime Picker = DateTime.Parse("2022-04-15");
        DateTime? value = DateTime.UtcNow;
        Action<DateTime?> ChangedCallback = (e) => { value = e!.Value; };
        var culture = CultureInfo.GetCultureInfo(cultureName);

        var clickOnValue = view switch
        {
            CalendarViews.Days => Picker.ToString("yyyy-MM-dd"),
            CalendarViews.Months => Picker.ToString("yyyy-MM"),
            CalendarViews.Years => Picker.ToString("yyyy"),
            _ => throw new ArgumentException("Not supported view")
        };

        // Arrange
        var calendar = Render(@<FluentCalendar Culture="@culture" View="@view" Value="@value" ValueChanged="ChangedCallback" PickerMonth="@Picker">Pick a date</FluentCalendar>);

        // Act
        var month = calendar.Find($"div[value='{clickOnValue}']");
        month?.Click();
        
        var selectedMonth = calendar.Find($"div[value='{clickOnValue}']");

        // Assert
        Assert.Equal(assertContent, selectedMonth.TextContent);
    }

    [Theory]
    [InlineData(CalendarViews.Days)]
    [InlineData(CalendarViews.Months)]
    [InlineData(CalendarViews.Years)]
    public void FluentCalendar_Minimum_View(CalendarViews view)
    {
        DateTime? value = DateTime.MinValue;

        // Arrange & Act
        var calendar = Render(@<FluentCalendar Value="@value" View="@view" Culture="@CultureInfo.GetCultureInfo("en-us")" />);
        var previous = calendar.Find($".previous");

        // Assert
        Assert.True(previous.HasAttribute("disabled"));
        calendar.Verify(suffix: view.GetDescription());
    }

    [Theory]
    [InlineData(CalendarViews.Days)]
    [InlineData(CalendarViews.Months)]
    [InlineData(CalendarViews.Years)]
    public void FluentCalendar_Maximum_View(CalendarViews view)
    {
        DateTime? value = DateTime.MaxValue;

        // Arrange & Act
        var calendar = Render(@<FluentCalendar Value="@value" View="@view" Culture="@CultureInfo.GetCultureInfo("en-us")" />);
        var previous = calendar.Find($".next");

        // Assert
        Assert.True(previous.HasAttribute("disabled"));
        calendar.Verify(suffix: view.GetDescription());
    }

    [Theory]
    [InlineData(CalendarViews.Days)]
    [InlineData(CalendarViews.Months)]
    [InlineData(CalendarViews.Years)]
    public void FluentCalendar_ReadOnly_View(CalendarViews view)
    {
        DateTime? value = DateTime.Parse("2022-04-15");

        // Arrange & Act
        var calendar = Render(@<FluentCalendar Value="@value" ReadOnly="true" View="@view" />);
        var component = calendar.Find($"div");
        var label = calendar.Find($".label");

        // Assert
        Assert.True(component.HasAttribute("readonly"));
        Assert.True(label.HasAttribute("readonly"));
    }
    

    [Theory]
    [InlineData(CalendarViews.Days, "May 2022")]
    [InlineData(CalendarViews.Months, "2023")]
    [InlineData(CalendarViews.Years, "2034 - 2045")]
    public void FluentCalendar_NextButton(CalendarViews view, string nextTitle)
    {
        DateTime? value = DateTime.Parse("2022-04-15");
        var culture = CultureInfo.GetCultureInfo("en-us");

        // Arrange
        var calendar = Render(@<FluentCalendar Culture="@culture" View="@view" Value="@value" AnimatePeriodChanges="false" />);

        // Act
        var nextButton = calendar.Find(".next");
        nextButton?.Click();

        var label = calendar.Find(".label");

        // Assert
        Assert.Equal(nextTitle, label.TextContent);
    }

    [Theory]
    [InlineData(CalendarViews.Days, "March 2022")]
    [InlineData(CalendarViews.Months, "2021")]
    [InlineData(CalendarViews.Years, "2010 - 2021")]
    public void FluentCalendar_PreviousButton(CalendarViews view, string nextTitle)
    {
        DateTime? value = DateTime.Parse("2022-04-15");
        var culture = CultureInfo.GetCultureInfo("en-us");

        // Arrange
        var calendar = Render(@<FluentCalendar Culture="@culture" View="@view" Value="@value" AnimatePeriodChanges="false" />);

        // Act
        var nextButton = calendar.Find(".previous");
        nextButton?.Click();

        var label = calendar.Find(".label");

        // Assert
        Assert.Equal(nextTitle, label.TextContent);
    }

    [Theory]
    [InlineData(CalendarViews.Days)]
    [InlineData(CalendarViews.Months)]
    [InlineData(CalendarViews.Years)]
    public void FluentCalendar_TitleClick(CalendarViews view)
    {
        DateTime? value = DateTime.Parse("2022-04-15");
        var culture = CultureInfo.GetCultureInfo("en-us");

        // Arrange
        var calendar = Render(@<FluentCalendar Culture="@culture" View="@view" Value="@value" AnimatePeriodChanges="false" />);

        // Act
        var title = calendar.Find(".label");
        title?.Click();

        // Assert
        calendar.Verify(suffix: view.GetDescription());
    }

    [Fact]
    public void FluentCalendar_TitleClick_SameMonthSelected()
    {
        DateTime? value = DateTime.Parse("2022-04-15");
        var culture = CultureInfo.GetCultureInfo("en-us");

        // Arrange
        var calendar = Render(@<FluentCalendar Culture="@culture" View="CalendarViews.Days" Value="@value" AnimatePeriodChanges="false" />);

        // Act
        var title = calendar.Find(".label");
        title!.Click();

        var april = calendar.Find($"div[value='2022-04']");
        april!.Click();

        // Assert
        Assert.Equal("April 2022", calendar.Find(".label").TextContent);
    }

    [Fact]
    public void FluentCalendar_TitleClick_SameYearSelected()
    {
        DateTime? value = DateTime.Parse("2022-04-15");
        var culture = CultureInfo.GetCultureInfo("en-us");

        // Arrange
        var calendar = Render(@<FluentCalendar Culture="@culture" View="CalendarViews.Months" Value="@value" AnimatePeriodChanges="false" />);

        // Act
        var title = calendar.Find(".label");
        title!.Click();

        var year2022 = calendar.Find($"div[value='2022']");
        year2022!.Click();

        // Assert
        Assert.Equal("2022", calendar.Find(".label").TextContent);
    }
}
